Publisher 有許多方式可以建立, 有單獨的, 復合的, 組合的, 媒介的, 不同的 Publisher 分別有不同的型別.其中以 Just
與 Future
較為常見.
一般來說, Publisher 是 Value type, 每次 Subscriber 訂閱時, 都會將原本定義的 Publisher 流程重頭執行, 不論其他複製的 Publisher 是否曾經訂閱發佈過.
struct Just<Output>
Just 很常被用來立即開始一個 Publisher chain, 在後面介紹 Error handling 時, 常被用來轉換 Error.
final class Future<Output, Failure: Error>
要注意的是 Future.init(attemptToFulfill:) 是带入一個 Closure, 而 attemptToFulfill 的型別是:
@escaping (@escaping Future<Output, Failure>.Promise) -> Void
其中 Promise 是 Future 的 typealias
typealias Future<Output, Failure>.Promise = (Result<Output, Failure>) -> Void
為了解釋這部分, 我們需要知道 Result, (Result)->Void 分別的用途.
Result 是一個 二分法
的實作, 相似於 Optional. 在 Optional 中有一個泛型與兩個分別, 將有與無分割開來:
enum Optional<Wrapped> {
case some(Warpped)
case none
}
而 Result 有兩個泛型與兩個分類, 將成功與失敗分割開來:
enum Result<Success, Failure:Error> {
case success(Success)
case failure(Failure)
}
值得注意的是, Result.init()是可以使用 throws 函式:
Result.init(catching body: () throws -> Success)
(Result)->Void, 是一個常見的 closure 帶法, 目的可以縮減結果情形:
success | failure | |
---|---|---|
success | V | |
failure | V |
在上表中, 我們不會發生同時成功與失敗, 也不會同時沒有成功與失敗, 因此可以更直覺的錯誤處理, 這部分可以參考 SwiftbySundell 的文章: The power of Result types in Swift
這部分沒有特別的明確中文翻譯, 筆者認定的解釋是: 延伸閉包, 用於在沒有 return 函式中執行完成後, 相依執行的部分, 使得函式可以具備延後設計的特性.
知道這兩個之後, 會更容易了解 Swift 中的 Promise, a.k.a. (Result)->Void
, 而 Future 就是將 Promise 轉化成 Publisher 的復合類型:
import Combine
func mayFailure(some:Some) throws -> TYPE {
...
}
Futrue<TYPE, Error> { promise in
do {
let type = try mayFailure(some:SOME)
promise(.success(type))
}catch let error {
promise(.failure(error))
}
}
另外還有其他的 Publisher, 需要搭配情境會比較好懂:
var
之前的 property wrapper, 請參考 Property wrappers to remove boilerplate code in Swift)簡單測驗: